#include "calculate.h"
#include "stmflash.h"
#include "control.h"
#include "adc.h"
#include "string.h"
#include "lcd.h"

uint16_t ADC_Values[ADC_MAX_NUM] = {0};

uint16_t EnterCommon = 0;
uint16_t i, j;
uint16_t adcx;
uint16_t adcc;
uint32_t sum;
float temp;
float ADCfront;
float ADCback;
float ADCdiode;
char * AllConditions[ERRORS_NUMS] = { "The data is normal",
																			"C1 Break", "C2 Break", "C3 Break", "C4 Break",
																			"L1 Short", "L2 Short", "L3 Short",
																			"C1 Short", "C2 Short", "C3 Short", "C4 Short",
																			"L1 Break", "L2 Break", "L3 Break" };

void ADCdetect(void)
{
	for(j = 0; j < 2; j++)
	{
		sum = 0;
		for(i = 0; i < ADC_MAX_NUM / 2; i++)
		{
			sum += ADC_Values[(2 * i) + j];
		}
		adcx = sum / (ADC_MAX_NUM / 2);
		
		temp = (float)adcx * (3.3 / 4096);
		adcx = temp;
		
		temp -= adcx;
		temp *= 1000;
		temp++;
		
		j == 0 ? (ADCfront = (float)adcx + temp / 1000) : (ADCback = (float)adcx + temp / 1000);
	}
}

void ImportData(void)
{
	double read_flash_back[ERRORS_NUMS], read_flash_front[ERRORS_NUMS];
	stmflash_read(FLASH_SAVE_ADCb, (uint16_t *)read_flash_back, ERRORS_NUMS * 4);
	stmflash_read(FLASH_SAVE_ADCa, (uint16_t *)read_flash_front, ERRORS_NUMS * 4);
	for(int i = 0; i < 15; i++)
	{
		Back_Errors[i] = read_flash_back[i];
		Front_Errors[i] = read_flash_front[i];
	}
}

void DetectionAlgo(void)
{
	EnterCommon = 1;
	DiodeDetectionAlgo();
	EnterCommonDetectionOper();
	HAL_Delay(1000);
	//ADCdetect();
	CommonDetect();
	AllrelayDown();
}

void DiodeDetectionAlgo(void)
{
	VolOnLeftOper();
	LCD_Fill(200, 400, 320, 480, WHITE);
	HAL_Delay(500);
	float VolLeft = ADC_CH2();
	
	VolOnRightOper();
	HAL_Delay(500);
	float VolRight = ADC_CH2();
	
	if(VOLTAGE_EARTH - VOLTAGE_OFFSET < VolLeft && VolLeft < VOLTAGE_EARTH + VOLTAGE_OFFSET && VOLTAGE_EARTH - VOLTAGE_OFFSET < VolRight && VolRight < VOLTAGE_EARTH + VOLTAGE_OFFSET)
	{
		strcpy(DiodeDetectionMsg, "S Short");
	} else if(VOLTAGE_DIODE - VOLTAGE_OFFSET < VolLeft && VolLeft < VOLTAGE_DIODE + VOLTAGE_OFFSET && VOLTAGE_DIODE - VOLTAGE_OFFSET < VolRight && VolRight < VOLTAGE_DIODE + VOLTAGE_OFFSET) {
		strcpy(DiodeDetectionMsg, "S Break");
	} else if(VOLTAGE_DIODE - VOLTAGE_OFFSET < VolLeft && VolLeft < VOLTAGE_DIODE + VOLTAGE_OFFSET && VOLTAGE_SOURCE - VOLTAGE_OFFSET < VolRight && VolRight < VOLTAGE_SOURCE + VOLTAGE_OFFSET) {
		strcpy(DiodeDetectionMsg, "D1 Break");
	}	else if(VOLTAGE_SOURCE - VOLTAGE_OFFSET < VolLeft && VolLeft < VOLTAGE_SOURCE + VOLTAGE_OFFSET && VOLTAGE_DIODE - VOLTAGE_OFFSET < VolRight && VolRight < VOLTAGE_DIODE + VOLTAGE_OFFSET) {
		strcpy(DiodeDetectionMsg, "D2 Break");
	}
}

float ADC_CH2(void)
{
	HAL_ADC_Start(&hadc2);
	HAL_ADC_PollForConversion(&hadc2, 100);
	adcc = HAL_ADC_GetValue(&hadc2);
	ADCdiode = (float)adcc * (3.3 / 4096);
	HAL_ADC_Stop(&hadc2);
	return ADCdiode;
}

void CommonDetect(void)
{
	if(0 <= (ADCback * 1000) && (ADCback * 1000) < 1000 * (0 + 0.04))
	{
		for(int i = ERRORS_NUMS - 1; i >= 8; i--)
		{
			if(Front_Errors[i] - 0.02 < ADCfront && ADCfront < Front_Errors[i] + 0.02)
			{
				strcpy(DetectionMsg, AllConditions[i]);
				return;
			}
		}
		return;
	}
	
	uint8_t min_index = 0, sec_min_index = 1;
	uint32_t Back_min_diff = abs_float(1000 * Back_Errors[0], 1000 * ADCback), Back_sec_min_diff = abs_float(1000 * Back_Errors[1], ADCback);
	uint32_t Vol_Sum = (uint32_t)(1000 * ADCfront) + (uint32_t)(1000 * ADCback);
	uint32_t min_Sum = (uint32_t)(1000 * Front_Errors[0]) + (uint32_t)(1000 * Back_Errors[0]);
	uint32_t sec_min_Sum = (uint32_t)(1000 * Front_Errors[1]) + (uint32_t)(1000 * Back_Errors[1]);
	
	if(abs_float(min_Sum, Vol_Sum) > abs_float(sec_min_Sum, Vol_Sum))
	{
		min_index = 1;
		sec_min_index = 0;
	}
	for(int i = 2; i < 8; i++)
	{
		uint32_t Back_now_diff = abs_float(1000 * Back_Errors[i], 1000 * ADCback);
		if(Back_now_diff < Back_sec_min_diff)
		{
			if(Back_now_diff < Back_min_diff)
			{
				Back_sec_min_diff = Back_min_diff;
				Back_min_diff = Back_now_diff;
				sec_min_index = min_index;
				min_index = i;
			} else if(Back_now_diff > Back_min_diff){
				Back_sec_min_diff = Back_now_diff;
				sec_min_index = i;
			}
		}
	}
	min_Sum = (uint32_t)(1000 * Front_Errors[min_index]) + (uint32_t)(1000 * Back_Errors[min_index]);
	sec_min_Sum = (uint32_t)(1000 * Front_Errors[sec_min_index]) + (uint32_t)(1000 * Back_Errors[sec_min_index]);
	abs_float(min_Sum, Vol_Sum) < abs_float(sec_min_Sum, Vol_Sum) ? strcpy(DetectionMsg, AllConditions[min_index]) : strcpy(DetectionMsg, AllConditions[sec_min_index]);
}

float abs_float(float a, float b)
{
	return a > b ? a - b : b - a;
}